package aufgabe1_mit_threads;

import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.net.Socket;

public class Server_Thread extends Thread {

	// Die Verbindung
	Socket connection = null;

	// InputStream
	private final int MAXZEICHEN = 257;
	private int timeout;
	private final int TIMEOUTMAX;
	
	// Der Master
	Server_Administration_Control_I_for_Server_Tread control;
	
	// Der Logger
	Logger logger;

	boolean server_run;

	public Server_Thread(Socket connection, Server_Administration_Control_I_for_Server_Tread control,Logger logger) {
		this.connection = connection;
		this.control = control;
		server_run = true;
		setDaemon(false);
		timeout = 0;
		TIMEOUTMAX = 120;
		this.logger = logger;
		logger.log("Server Thread", "Server Thread", "Erzeugt");
	}

	@Override
	public void run() {
		InputStream eingang;
		PrintWriter out;
		
		try{
		eingang = connection.getInputStream();
		out = new PrintWriter(connection.getOutputStream(), true);
		}catch (IOException e){
			control.server_thread_counter_down();
			logger.log("Server Thread", "Error", "FEHLER BEI CONNECTIONAUFBAU");
			return;
		}
		
		try{
		while (server_run) {
			
			if(timeout > TIMEOUTMAX){
				eingang.close();
				out.close();
				connection.close();
				control.server_thread_counter_down();	
				logger.log("Server Thread", "Server Thread", "Timed out");
				return;
			}
			
			// Handle Connection
			byte [] zeichen = new byte [MAXZEICHEN];
			int anzahl = eingang.available();
			if (anzahl > 0){
				logger.log("Server Thread", "Anzahl der Bytes(available):", "" + anzahl);
				timeout = 0;
				int number_zeichen = eingang.read(zeichen);
			
				String input = "";
				String chars = new String(zeichen);
				
				for(int i = 0; i < number_zeichen - 2; i++){
					input = input + chars.charAt(i);
				}
				// zeilenumbrueche entfernen			
				input.replaceAll("\r\n" , "");
				input.replaceAll("\n" , "");
				input.replaceAll("\r" , "");
				
				logger.log("Server Thread", "Inputlaenge","" + input.length());
				
				int rest = eingang.available();
					if(rest > 0){
						eingang.skip(rest+1);
					}
				String[] splitInput = input.split(" ", 2);
				String output = "ERROR";
				logger.log("Server Thread", "Splitinput 0", "Begin :" + splitInput[0] + ": End");
				if (splitInput.length == 2) {
					logger.log("Server Thread", "Splitinput 1","Begin :" + splitInput[1] + ": End");
					if (splitInput[0].equals("LOWERCASE")) {
						output = "OK " + splitInput[1].toLowerCase();
					} else if (splitInput[0].equals("UPPERCASE")) {
						output = "OK " + splitInput[1].toUpperCase();
					} else if (splitInput[0].equals("REVERSE")) {
						output = "OK " + new StringBuffer(splitInput[1]).reverse()
										.toString();
					} else if (splitInput[0].equals("SHUTDOWN")) {
						boolean feedback = control.try_shutdown(splitInput[1]);
						if (feedback) {
							server_run = false;
							output = "OK";
						} else {
							output = "ERROR Wrong Password";
						}
					} else {
						output = "ERROR " + input;
					}
				} else {
					if (splitInput[0].equals("BYE")) {
						output = "BYE";
						server_run = false;
					} else if (splitInput[0].equals("SHUTDOWN")) {
						output = "ERROR Missing Password";
					} else {
						output = "ERROR " + input;
					}
				}
				logger.log("Server Thread", "OUTPUT:", "Begin :" + output + ": End");
				out.println(output);
			} else {
				timeout++;
				my_sleep();
			}
		}
		eingang.close();
		out.close();
		connection.close();
		control.server_thread_counter_down();
		logger.log("Server Thread", "Server Thread", "Closing" );
		}catch (IOException e){
			control.server_thread_counter_down();
			logger.log("Server Thread", "ERROR", "IOException");
		}
	}

	public void my_sleep(){
		try {
			sleep(1000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
}
